#pragma once

#include <memory>

#include "planner/optimizer_context.h"
#include "planner/property_set.h"

namespace optimizer {

class Optimizer {
 public:
  DISALLOW_COPY_AND_MOVE(Optimizer);

  explicit Optimizer(OptimizerContext *ctx, const uint64_t task_execution_timeout)
      : context_(ctx), task_execution_timeout_(task_execution_timeout) {}

  group_id_t BuildPlanTree(std::shared_ptr<Operator> op_tree, PropertySet *required_props);

 private:
  void OptimizeLoop(group_id_t root_group_id, PropertySet *required_props);

  void ExecuteTaskStack(group_id_t root_group_id, OptimizationContext *root_context) const;

  OptimizerContext *context_;
  const uint64_t task_execution_timeout_;
};

}  // namespace optimizer
